<template>
  <div>
    <div>
      <a-button :loading="loading" type="primary" @click="click">裁切</a-button>
      <a-upload
        v-model:file-list="fileList"
        :max-count="1"
        :before-upload="beforeUpload"
      >
        <a-button>
          <upload-outlined></upload-outlined>
          上传
        </a-button>
      </a-upload>
      <span class="text-yellow-600"
        >请做好图片裁剪，滚轮缩放图片，以便适应手机端显示375*385</span
      >
    </div>
    <div class="container">
      <div>
        <div class="content-box">
          <vue-cropper
            :autoCrop="true"
            :outputSize="1"
            :enlarge="10"
            ref="cropper"
            :minContainerWidth="375"
            :minContainerHeight="385"
            :cropBoxResizable="false"
            :outputQuality="1"
            :cropBoxData="{ width: 375, height: 385 }"
            :high="false"
            :img="imageUrl"
            :fixed="false"
            :centerBox="true"
            :canMoveBox="true"
            :canScale="true"
            :canMove="true"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { createVNode, h, watch, ref } from "vue";
import { Modal, message } from "ant-design-vue";
import Api from "@/api/backend/api";
import { VueCropper } from "vue-cropper";
import { UploadOutlined } from "@ant-design/icons-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  uploadUrl: {
    type: String,
    default: "/api/upload",
  },
});

const cutImg = ref("");
const fileList = ref([]);
const imageUrl = ref("");
const emit = defineEmits(["update:modelValue"]);

// 获取env变量
const baseUrl = import.meta.env.VITE_BASE_OSS_URL;

watch(
  () => props.modelValue,
  (newVal) => {
    imageUrl.value = newVal;
  },
  {
    deep: true,
    immediate: true,
  }
);

const beforeUpload = (file) => {
  let img = new Image();
  img.crossOrigin = "anonymous";
  img.src = URL.createObjectURL(file);
  img.onload = function () {
    imageUrl.value = img.src;
  };
  return false;
};

const cropper = ref();
const loading = ref(false);

const click = () => {
  if (imageUrl.value === "") {
    return message.error("请先上传图片");
  }
  loading.value = true;
  cropper.value.getCropBlob((data) => {
    open(data);
  });
};

const updateCut = (img: string) => {
  emit("update:modelValue", img);
};

const open = (blob) => {
  let img = new Image();
  img.src = URL.createObjectURL(blob);
  Modal.confirm({
    title: "确定裁切吗？",
    centered: true,
    width: 600,
    maskClosable: false,
    icon: createVNode(ExclamationCircleOutlined),
    content: h(
      "div",
      { style: "color:red;" },
      h("img", {
        src: img.src,
        style: "width:100%;",
        id: "cropimg",
        mode: "widthFix",
      })
    ),
    okText: "保存",
    cancelText: "取消",
    onOk: async () => {
      cutImg.value = img.src;
      loading.value = false;
      const file = new File([blob], "cropped.png", { type: "image/png" });
      const url = await Api.uploadController.upload({}, file);
      const cropperedUrl = baseUrl + "/" + url;
      updateCut(cropperedUrl);
    },
    onCancel() {
      loading.value = false;
    },
  });
};
</script>

<style lang="less" scoped>
.container {
  padding: 10px;
  box-sizing: border-box;
  width: auto;
  height: auto;
  display: flex;
}

.content-box {
  height: 400px;
  width: 400px;
  box-sizing: border-box;
  border: 1px solid #ededed;
  margin: 5px;
  box-shadow: 1px 1px 1px #ededed;
}

.preview-box {
  width: 400px;
  height: 400px;
  background-color: #74b9ff;
  border: 1px dotted #ededed;
  box-sizing: border-box;
  box-shadow: 1px 1px 1px #ededed;

  .pre-title {
    color: #fff;
    font-size: 14px;
  }

  .pre-box {
    width: 200px;
    text-align: center;
  }
}

.ant-upload {
  width: 200px;
  height: 200px;
}

.ant-upload-select {
  width: 200px;
  height: 200px;
}

.ant-upload-select-text {
  width: 200px;
  height: 200px;
}
</style>
